/*
 * Copyright 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.sockets.client;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * A helper class for Sockets classes. This subclass of {@link java.util.ArrayList} assumes
 * that all objects added to it will be of type {@link com.google.gwt.sockets.client.SocketListener}.
 * All methods notify listeners using DeferredCommand to free a thread from socket object. For example,
 * Flash will throw exception, if one of listeners show message with <b>alert</b> function (blocks a thread
 * from Flash) and user doesn't close it in 15 seconds.
 *
 * @author Aleksey Lagoshin
 */
public class SocketListenerCollection extends ArrayList {

  /**
   * Fires a ready event to all listeners.
   */
  public void fireReady() {
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        for (Iterator it = iterator(); it.hasNext();) {
          SocketListener listener = (SocketListener) it.next();
          listener.onReady();
        }
      }
    });
  }

  /**
   * Fires a connection event to all listeners.
   */
  public void fireConnect() {
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        for (Iterator it = iterator(); it.hasNext();) {
          SocketListener listener = (SocketListener) it.next();
          listener.onConnect();
        }
      }
    });
  }

  /**
   * Fires a close connection event to all listeners.
   */
  public void fireCloseConnection() {
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        for (Iterator it = iterator(); it.hasNext();) {
          SocketListener listener = (SocketListener) it.next();
          listener.onCloseConnection();
        }
      }
    });
  }

  /**
   * Fires a data event to all listeners.
   *
   * @param loadedBytes number of received bytes
   */
  public void fireData(final int loadedBytes) {
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        for (Iterator it = iterator(); it.hasNext();) {
          SocketListener listener = (SocketListener) it.next();
          listener.onData(loadedBytes);
        }
      }
    });
  }

  /**
   * Fires a security error event to all listeners.
   *
   * @param message detailed message
   */
  public void fireSecurityError(final String message) {
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        for (Iterator it = iterator(); it.hasNext();) {
          SocketListener listener = (SocketListener) it.next();
          listener.onSecurityError(message);
        }
      }
    });
  }

  /**
   * Fires an input/output error event to all listeners.
   *
   * @param message detailed message
   */
  public void fireIOError(final String message) {
    DeferredCommand.addCommand(new Command() {
      public void execute() {
        for (Iterator it = iterator(); it.hasNext();) {
          SocketListener listener = (SocketListener) it.next();
          listener.onIOError(message);
        }
      }
    });
  }

}
